package org.beehoo.web.framework.dao;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

import org.beehoo.web.framework.context.SpringContextHolder;

public class JdbcOperator {
	
	private static JdbcOperator instance;
	
	private JdbcTemplate jdbcTemplate;

	private SimpleJdbcTemplate simpleJdbcTemplate;

	public static synchronized JdbcOperator getInstance() {
		if (instance == null) {
			instance = new JdbcOperator();
		}
		return instance;
	}

	private JdbcOperator() {
		this.jdbcTemplate = SpringContextHolder.getBean(JdbcTemplate.class);
		this.simpleJdbcTemplate = new SimpleJdbcTemplate(jdbcTemplate);
	}

	/*
	 * 
	 */
	public <T> List<T> queryForObjectList(String sql, Class<T> requiredType, Object... args) throws DataAccessException {
		if (isPrimaryType(requiredType))
			return jdbcTemplate.queryForList(sql, requiredType, args);
		else
			return simpleJdbcTemplate.query(sql, new BeanPropertyRowMapper<T>(requiredType), args);
	}
	
	/*
	 * 
	 */
	public List<Map<String, Object>> queryForMapList(String sql, Object... args) throws DataAccessException {
		return simpleJdbcTemplate.queryForList(sql, args);
	}
	
	public Map<String, Object> queryForMap(String sql, Object... args) throws DataAccessException {
		Map<String, Object> result = new HashMap<String , Object>();
		try {
			result = simpleJdbcTemplate.queryForMap(sql, args);
		} catch (Exception e) {
		}
		return result;
	}
	
	public int update(String sql, Map<String, ?> args) throws DataAccessException {
		return simpleJdbcTemplate.update(sql, args);
	}
	
	private boolean isPrimaryType(Class classType) {
		for (Class type : primaryClassArray) {
			if (type.equals(classType))
				return true;
		}
		return false;
	}
	
	private Class[] primaryClassArray = new Class[] { String.class, boolean.class, Boolean.class, byte.class, Byte.class, short.class, Short.class, int.class, Integer.class, long.class, Long.class,
			float.class, Float.class, double.class, Double.class, byte[].class, java.sql.Date.class, java.sql.Time.class, java.sql.Timestamp.class, BigDecimal.class, java.sql.Blob.class,
			java.sql.Clob.class };
}
